import 'package:flutter/material.dart';

class DashedBorderPainter extends CustomPainter {
  final double borderWidth;
  final Color borderColor;
  final double dashSpace;
  final double dashWidth;
  final double radius;

  /// 虚线样式 默认box:虚线框
  final DashBoxType type;

  DashedBorderPainter(
      {required this.borderWidth,
      required this.borderColor,
      required this.dashSpace,
      required this.dashWidth,
      required this.radius,
      required this.type});

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = borderWidth;

    final dashPath = Path();
    double x = 0.0;
    double radioPoint =
        radius > 0 && radius > dashWidth / 2 ? dashWidth / 2 : radius;
    if (radius > 0) {
      x = radioPoint;
    }
    while (x < size.width - (radius == 0 ? radius : radioPoint)) {
      dashPath.moveTo(x, 0);
      if (radius > 0 &&
          x + dashWidth + dashSpace >= (size.width - radioPoint)) {
        dashPath.lineTo(size.width - radioPoint, 0);
      } else {
        if (x + dashWidth < size.width) {
          dashPath.lineTo(x + dashWidth, 0);
        }
      }
      x += dashWidth + dashSpace;
    }
    if (type == DashBoxType.box) {
      double y = 0.0;
      if (radius > 0) {
        dashPath.arcToPoint(Offset(size.width, radioPoint),
            radius: Radius.circular(radius));
        y = radioPoint;
      }

      while (y < size.height - (radius == 0 ? radius : radioPoint)) {
        dashPath.moveTo(size.width, y > size.height ? size.height : y);

        if (radius > 0 &&
            (y + dashWidth + dashSpace) >= (size.height - radioPoint)) {
          dashPath.lineTo(size.width, size.height - radioPoint);
        } else {
          dashPath.lineTo(size.width,
              (y + dashWidth) > size.height ? size.height : (y + dashWidth));
        }
        y += dashWidth + dashSpace;
      }

      double xx = size.width;
      if (radius > 0) {
        dashPath.arcToPoint(Offset(size.width - radioPoint, size.height),
            radius: Radius.circular(radius));
        xx = size.width - radioPoint;
      }

      while (xx > 0 + (radius > 0 ? radioPoint : 0)) {
        dashPath.moveTo(xx, size.height);
        if (radius > 0 && xx - dashWidth - dashSpace < radioPoint) {
          dashPath.lineTo(radioPoint, size.height);
        } else {
          if (xx - dashWidth > 0) {
            dashPath.lineTo(xx - dashWidth, size.height);
          }
        }
        xx -= dashWidth + dashSpace;
      }

      double yy = size.height;
      if (radius > 0) {
        dashPath.arcToPoint(Offset(0, size.height - radioPoint),
            radius: Radius.circular(radius));
        yy = size.height - radioPoint;
      }

      while (yy > 0 + (radius > 0 ? radioPoint : 0)) {
        dashPath.moveTo(0, yy < 0 ? 0 : yy);
        if (radius > 0 && yy - dashWidth - dashSpace < radioPoint) {
          dashPath.lineTo(0, radioPoint);
        } else {
          dashPath.lineTo(0, (yy - dashWidth) < 0 ? 0 : (yy - dashWidth));
        }
        yy -= dashWidth + dashSpace;
      }
      if (radius > 0 && yy > 0) {
        dashPath.arcToPoint(Offset(radioPoint, 0),
            radius: Radius.circular(radius));
      }
    }

    canvas.drawPath(dashPath, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

enum DashBoxType { box, line }

// ignore: must_be_immutable
class KqDashedBox extends StatelessWidget {
  /// 边框
  final double borderWidth;

  /// 边框颜色
  final Color borderColor;

  /// 虚线间距
  final double dashSpace;

  /// 虚线宽度
  final double dashWidth;

  /// 圆角（圆角还和虚线宽度有关）
  final double? radius;

  /// 虚线样式 默认box:虚线框
  final DashBoxType? type;
  Widget? child;

  KqDashedBox(
      {super.key,
      required this.borderWidth,
      required this.borderColor,
      required this.dashSpace,
      required this.dashWidth,
      this.radius,
      this.type = DashBoxType.box,
      this.child});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: DashedBorderPainter(
          borderWidth: borderWidth,
          borderColor: borderColor,
          dashSpace: dashSpace,
          dashWidth: dashWidth,
          radius: radius ?? 0,
          type: type!),
      child: child ?? Container(),
    );
  }
}
